package com.qf.realm;

import com.qf.dao.SysUsersDao;
import com.qf.pojo.SysUsers;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.WildcardType;
import java.util.Arrays;
import java.util.Set;

/**
 * 自定义的RealM
 * <p>
 * 数据来源于Mysql数据库
 * 1、数据库叫什么名
 * 2、数据库表叫什么名
 * 3、角色是怎么查询
 * 4、权限是怎么查询
 * 我全不知道
 * <p>
 * <p>
 * AuthenticatingRealm : 认证   查询用户名及密码是否正确
 * <p>
 * AuthorizingRealm: 授权   查询用户名及密码是否正确 、 查询角色及权限
 *
 * @author lixu
 */
public class MyRealm extends AuthorizingRealm {


    @Autowired
    private SysUsersDao sysUsersDao;


    /**
     * 授权
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        System.out.println("======授权doGetAuthorizationInfo");
        //1:获取出用户对象  张三
        SysUsers sysUsers = (SysUsers) principals.getPrimaryPrincipal();
        //2:根据用户对象 ID 查询此用户有哪些角色
        Set<String> roles = sysUsersDao.findRolesByUid(sysUsers.getId()); //哪些角色
        System.out.println("roles:" + Arrays.asList(roles));//roles:[管理员,开发]
        //问题1： Set集合：去掉重复  管理员 开发人员
        //3:根据 用户ID查询所有对应的权限集合
        Set<String> stringPermissions = sysUsersDao.findPermsByUid(sysUsers.getId());//哪些权限   sys:memu:add
        //4:授权对象
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(stringPermissions);
        return authorizationInfo;//一次  （只能问一件事 你有管理员角色 吗 、  你有sys:user:*权限
    }

    /**
     * 认证
     *
     * @param token
     * @return
     * @throws AuthenticationException AuthenticationToken token
     *                                 <p>
     *                                 UsernamePasswordToken authenticationToken = new UsernamePasswordToken("zhangsan",md5Hash.toString());
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
/*        String principal = (String) token.getPrincipal();
        char[] credentials = (char[]) token.getCredentials();*/


        System.out.println("======认证doGetAuthenticationInfo");
        //1:将参数进行向下强转  获取用户名密码对象
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        //2:用户名
        String username = usernamePasswordToken.getUsername();
        //3：密码 ( 密文）
        String password = new String(usernamePasswordToken.getPassword());

        //4:校验用户名或密码是否正确
        SysUsers sysUsers = sysUsersDao.findUserByUsername(username);
        //4.1: 判断sysUsers是否存在
        if (null == sysUsers) {
            System.out.println("===用户名不存在===");
            throw new UnknownAccountException("用户名不存在");//停止继续
        }
        //4.2  判断密码是否正确
        if (!sysUsers.getPassword().equals(password)) {
            System.out.println("===密码不正确===");
            throw new IncorrectCredentialsException("密码不正确");//停止继续
        }
        if(sysUsers.getStatus()  != 1){
            throw new LockedAccountException("帐户被锁定");
        }

        //4.3:全正确 放行
        return new SimpleAuthenticationInfo(sysUsers, password, this.getName());
    }
}
